Day 6 我們學會使用 Loop,讓程式可以重複執行。
但如果今天要保存多筆商品:
string product1 = "TXF";
string product2 = "MXF";
string product3 = "EXF";
只有三筆看起來還好。
但如果有 100 筆、1000 筆資料,就不適合一直建立新的 Variable。
這時可以使用:
Array(陣列)
Array 用來集中管理多筆相同 Type 的資料。
今天會學到:
for 搭配 Arrayforeach
for 與 foreach
IndexOutOfRangeException
使用 Array 後,可以把多筆相同 Type 的資料集中管理:
string[] products = { "TXF", "MXF", "EXF" };
可以理解成:
products
↓
┌─────┬─────┬─────┐
│ TXF │ MXF │ EXF │
└─────┴─────┴─────┘
這樣就能使用一個 Variable 管理多筆資料。
所以可以先記住:
多筆相同 Type 的資料
↓
Array
Array 的基本語法:
Type[] variableName
例如:
int[] quantities;
decimal[] prices;
string[] products;
其中:
int
→ 一個 int
int[]
→ 一組 int
[] 代表這個 Type 是 Array。
可以在建立時直接放入資料:
string[] products =
{
"TXF",
"MXF",
"EXF"
};
也可以寫成:
int[] quantities = { 1, 3, 5, 10 };
Array 裡面的元素必須符合相同 Type。
例如:
int[] quantities = { 1, 2, 3 };
就不能放入:
"Hello"
因為 "Hello" 是 string,不是 int。
也可以先指定 Array 的長度:
int[] quantities = new int[3];
代表:
建立一個可以存放 3 個
int的 Array。
Array 有一個重要特性:
Array 建立之後,長度固定。
例如:
int[] quantities = new int[3];
這個 Array 就固定有 3 個位置。
要注意:
長度固定,不代表裡面的資料不能修改。
後面仍然可以修改每個位置所儲存的 Value。
如果未來需要經常:
新增資料
刪除資料
動態改變資料數量
通常會使用:
List<T>
後面的 Collection 章節會再正式介紹。
目前先記住:
Array
→ 儲存多筆相同 Type 的資料
→ 建立後長度固定
→ 元素內容仍然可以修改
建立 Array 後,要怎麼取得裡面的資料?
需要使用:
Index(索引)
例如:
string[] products = { "TXF", "MXF", "EXF" };
每個元素都有自己的 Index:
Value TXF MXF EXF
Index 0 1 2
注意:
Array 的 Index 從 0 開始。
這稱為:
Zero-based Index
所以:
第一個元素 → Index 0
第二個元素 → Index 1
第三個元素 → Index 2
Console.WriteLine(products[0]);
Console.WriteLine(products[1]);
Console.WriteLine(products[2]);
結果:
TXF
MXF
EXF
例如:
products[0]
代表第一個元素:
TXF
前面建立:
int[] quantities = new int[3];
現在就可以透過 Index 放入資料:
quantities[0] = 10;
quantities[1] = 20;
quantities[2] = 30;
可以理解成:
Value 10 20 30
Index 0 1 2
Index 不只能讀取資料,也可以修改資料。
例如:
string[] products = { "TXF", "MXF", "EXF" };
products[1] = "FXF";
原本:
Value TXF MXF EXF
Index 0 1 2
修改後:
Value TXF FXF EXF
Index 0 1 2
所以:
Console.WriteLine(products[1]);
結果:
FXF
這也說明:
Array 的長度固定,但元素內容可以修改。
如果想知道 Array 有多少元素,可以使用:
.Length
例如:
string[] products = { "TXF", "MXF", "EXF" };
Console.WriteLine(products.Length);
結果:
3
也就是:
products.Length
→ 3
假設:
string[] products = { "TXF", "MXF", "EXF" };
Array 的長度:
Length = 3
但合法的 Index:
0
1
2
所以:
Length
→ 元素數量
當 Array 至少有一個元素時:
Length - 1
→ 最後一個 Index
因此最後一筆資料可以這樣取得:
Console.WriteLine(products[products.Length - 1]);
結果:
EXF
這裡最重要的是:
Length 是元素數量,不是最後一個 Index。
如果存取不存在的 Index:
string[] products = { "TXF", "MXF", "EXF" };
Console.WriteLine(products[3]);
執行時會發生:
IndexOutOfRangeException
因為:
Length = 3
合法 Index:
0
1
2
並不存在:
Index 3
所以:
使用 Array 時,要確認 Index 沒有超出範圍。
for 處理 ArrayDay 6 學到的 for,現在就可以真正拿來處理一組資料。
string[] products = { "TXF", "MXF", "EXF" };
for (int i = 0; i < products.Length; i++)
{
Console.WriteLine(products[i]);
}
結果:
TXF
MXF
EXF
這裡:
int i = 0;
代表從第一個 Index 開始。
而:
i < products.Length
代表:
i < 3
所以執行流程:
i = 0 → products[0] → TXF
i = 1 → products[1] → MXF
i = 2 → products[2] → EXF
i = 3 → false → 結束
這就是為什麼處理 Array 時很常看到:
i < products.Length
而不是:
i <= products.Length
如果使用 <=:
for (int i = 0; i <= products.Length; i++)
最後會嘗試讀取:
products[3]
造成:
IndexOutOfRangeException
這也是 Day 6 提過的:
Off-by-one Error
foreach如果只是想逐筆讀取 Array 裡面的元素,可以使用:
foreach
例如:
string[] products = { "TXF", "MXF", "EXF" };
foreach (string product in products)
{
Console.WriteLine(product);
}
結果:
TXF
MXF
EXF
可以理解成:
products
↓
逐一取得元素
↓
product
↓
執行程式
每次 Loop:
第一次 → product = "TXF"
第二次 → product = "MXF"
第三次 → product = "EXF"
直到所有元素都處理完成。
for 還是 foreach?兩者都可以走訪 Array,但適合的情境不同。
使用 for:
for (int i = 0; i < products.Length; i++)
{
Console.WriteLine(
$"Index: {i}, Product: {products[i]}"
);
}
結果:
Index: 0, Product: TXF
Index: 1, Product: MXF
Index: 2, Product: EXF
使用 foreach:
foreach (string product in products)
{
Console.WriteLine(product);
}
可以先簡單記成:
| 情境 | 選擇 |
|---|---|
| 需要 Index | for |
| 逐筆讀取元素 | foreach |
如果沒有使用 Index 的需求,
foreach通常會比較簡潔。
最後把 Array、Loop 與前面學過的 Operator 結合起來。
建立一組價格:
decimal[] prices =
{
100m,
200m,
300m
};
建立總金額:
decimal total = 0m;
使用 foreach 逐筆加總:
foreach (decimal price in prices)
{
total += price;
}
最後:
Console.WriteLine($"Total: {total}");
結果:
Total: 600
完整程式:
decimal[] prices =
{
100m,
200m,
300m
};
decimal total = 0m;
foreach (decimal price in prices)
{
total += price;
}
Console.WriteLine($"Total: {total}");
執行流程:
Array
↓
foreach
↓
逐筆取得 price
↓
total += price
↓
計算總和
所以:
Array 負責保存多筆資料,Loop 負責逐筆處理資料。
今天我們解決的問題是:
多筆相同 Type 的資料,要怎麼集中管理?
答案就是:
Array
Array
→ 儲存多筆相同 Type 的資料
→ 建立後長度固定
→ 元素內容仍然可以修改
Array 使用 Zero-based Index:
Value TXF MXF EXF
Index 0 1 2
所以:
products[0]
代表第一個元素。
products.Length
代表:
元素數量
當 Array 至少有一個元素時:
Length - 1
代表:
最後一個 Index
for / foreach需要 Index
→ for
逐筆讀取元素
→ foreach